﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PopShotController : MonoBehaviour {



	// singleton list to hold all our projectiles
	static private List<PopShotController> popShotControllers;

	private Vector3 myDirection;
	private bool hitObject;
	public float bulletSpeed;

	public AudioClip wallHitSound;
	public AudioClip enemyHitSound;
	private AudioSource soundClip;

	//--------------------------------------------------------------------------
	// static public methods
	//--------------------------------------------------------------------------
	static public void Reset()
	{
		// for each projectile
		foreach(PopShotController popShotController in popShotControllers)
		{
			// configure it
			popShotController.Configure();
		}
	}

	static public PopShotController Spawn(Vector3 location, int heading)
	{
		// search for the first free popShotController
		foreach(PopShotController popShotController in popShotControllers)
		{
			// if disabled, then it's available
			if(popShotController.gameObject.activeSelf == false)
			{
				// set it up
				popShotController.transform.position = location;
				// Set the angle from the heading
				popShotController.transform.Rotate(0,0,heading);
				// convert the heading into a vector
				popShotController.myDirection = Quaternion.AngleAxis(heading, Vector3.forward) * Vector3.right;
				// switch it back on
				popShotController.gameObject.SetActive(true);
				// Turn collider and sprite renderer back on
				popShotController.GetComponent<SpriteRenderer>().enabled = true;
				popShotController.hitObject = false;
				// return a reference to the caller
				return popShotController;
			}
		}
		// we normally wouldn't get here unless the player is firing rapidly
		// in some games we always want the pool request to succeed, if so
		// then we would instantiate another one here if we needed
		// in our case, it's part of the design that you can only have
		// a limited number of shots active at any one time
		return null;
	}

	//--------------------------------------------------------------------------
	// public methods
	//--------------------------------------------------------------------------
	//--------------------------------------------------------------------------
	// protected mono methods
	//--------------------------------------------------------------------------
	protected void Awake()
	{
		// does the pool exist yet?
		if(popShotControllers == null)
		{
			// lazy initialize it
			popShotControllers = new List<PopShotController>();
		}
		// add myself
		popShotControllers.Add(this);
	}

	protected void OnBecameInvisible()
	{
		gameObject.transform.rotation = Quaternion.identity;
	}

	protected void OnDestroy()
	{
		// remove myself from the pool
		popShotControllers.Remove(this);
		// was I the last one?
		if(popShotControllers.Count == 0)
		{
			// remove the pool itself
			popShotControllers = null;
		}
	}

	protected void OnTriggerEnter2D(Collider2D collider)
	{

		// Check which floor the player is on
		GameObject player = GameObject.FindWithTag("Player");
		int pFloor = player.GetComponent<PlayerController>().playerFloor;

		if( pFloor == 0 && collider.gameObject.tag == "BulletCollider")
		{
			hitObject = true;
			PopShotImpactController.Spawn(transform.position);
			StartCoroutine(PlaySound(wallHitSound));
			gameObject.GetComponent<SpriteRenderer>().enabled = false;
		}

		if( pFloor == 0 && collider.gameObject.tag == "Enemy")
		{
			hitObject = true;
			PopShotImpactController.Spawn(transform.position);
			StartCoroutine(PlaySound(enemyHitSound));
			gameObject.GetComponent<SpriteRenderer>().enabled = false;
		}
	}

	protected void Start()
	{
		soundClip = GetComponent<AudioSource>();
		hitObject = false;
		gameObject.SetActive(false);
	}

	protected void Update()
	{
		if( hitObject == false)
		{
			transform.position += myDirection * (Time.deltaTime * bulletSpeed);
		}
	}

	//--------------------------------------------------------------------------
	// Coroutines
	//--------------------------------------------------------------------------
	IEnumerator PlaySound(AudioClip clip)
	{
		soundClip.clip = clip;
		soundClip.Play();
		yield return new WaitForSeconds (soundClip.clip.length);
		gameObject.SetActive(false);
	}

	//--------------------------------------------------------------------------
	// private methods
	//--------------------------------------------------------------------------
	private void Configure()
	{
		// just disable myself so I'm available for use
		gameObject.SetActive(false);
	}
}
